#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
#include <mutex>
#include <thread>
#include <vector>
using namespace std;
class HungryInstance
{
public:
	static HungryInstance* GetInstance()
	{
		return _ptr;
	}

	void Add(const string& str)
	{
		_mtx.lock();
		v.push_back(str);
		_mtx.unlock();
	}

	void Print()
	{
		_mtx.lock();
		for (auto& e : v)
		{
			cout << e << endl;

		}
		_mtx.unlock();
	}




private:
	HungryInstance()
	{};
	HungryInstance(const HungryInstance& h) = delete;
	HungryInstance& operator=(const HungryInstance& h) = delete;
	static HungryInstance* _ptr;
	vector<string> v;
	mutex _mtx;
};
HungryInstance* HungryInstance::_ptr = new HungryInstance;



class LazyInstance
{
public:
	static LazyInstance* GetInstance()
	{
		if (_ptr == nullptr)
		{
			_smtx.lock();
			if (_ptr == nullptr)
			{
				_ptr = new LazyInstance;
			}
			_smtx.unlock();
		}
			return _ptr;
	}

	static void Delete()
	{
		_smtx.lock();
		if (_ptr)
		{
			delete _ptr;
		}
		_smtx.unlock();
	}
	~LazyInstance()
	{
		cout << "delete" << endl;
	}

	class GC
	{
	public:
		~GC()
		{
			Delete();
		}
	};



	void Add(const string& str)
	{
		_mtx.lock();
		_v.push_back(str);
		_mtx.unlock();
	}

	void Print()
	{
		_mtx.lock();
		for (auto& e : _v)
		{
			cout << e << endl;
		}
		_mtx.unlock();
	}

private:
	LazyInstance()
	{}
	LazyInstance(const LazyInstance& l) = delete;
	LazyInstance& operator=(const LazyInstance& l) = delete;
	static GC gc;
	static LazyInstance* _ptr;
	vector<string> _v;
	static mutex _smtx;
	mutex _mtx;
};

LazyInstance::GC LazyInstance::gc;
LazyInstance* LazyInstance::_ptr = nullptr;
mutex LazyInstance::_smtx;